# include "LibSVMClassifier.h"

/**
  constructor
*/  
LibSVMClassifier::LibSVMClassifier()
{
	model=NULL;
	predict_probability=0;
	nr_class=0;
	svm_type=0;
	x= NULL;
}

LibSVMClassifier::LibSVMClassifier(const LibSVMClassifier &obj)
{
	
}

/**
  set parameter
*/  
void LibSVMClassifier::setParamters( int pred_prob )
{
	predict_probability = pred_prob;
}

LibSVMClassifier::~LibSVMClassifier()
{
	if( model != NULL) svm_free_and_destroy_model(&model);
	if( x != NULL) free(x);
}

void LibSVMClassifier::exit_input_error(int line_num)
{
	fprintf(stderr,"Wrong input format at line %d\n", line_num);
	exit(1);
}

/*
   string으로 feature 입력받고, 그 결과를 return
   0보다 작으면 negi, 크면 pos
*/
double LibSVMClassifier::classify(  std::string   feature)
{
	std::string line = feature+" ";
	int total = 0;
	double *prob_estimates=NULL;
	if(predict_probability)
	{
		return 0.0;
	}

	int i = 0;
	double target_label, predict_label;
	char *idx, *val, *label, *endptr;
	int inst_max_index = -1; // strtol gives 0 if wrong format, and precomputed kernel has <index> start from 0
	{
		label = strtok((char*)line.c_str()," \t");
		target_label = strtod(label,&endptr);
		if(endptr == label)
			exit_input_error(total+1);
		while(1)
		{
			idx = strtok(NULL,":");
			val = strtok(NULL," \t");

			if(val == NULL)
				break;
			errno = 0;
			x[i].index = (int) strtol(idx,&endptr,10);
			if(endptr == idx || errno != 0 || *endptr != '\0' || x[i].index <= inst_max_index)
				exit_input_error(total+1);
			else
				inst_max_index = x[i].index;
			errno = 0;
			x[i].value = strtod(val,&endptr);
			if(endptr == val || errno != 0 || (*endptr != '\0' && !isspace(*endptr)))
				exit_input_error(total+1);

			++i;
		}
		x[i].index = -1;
	
	    predict_label = svm_predict(model,x);
		++total;
	}

	if(predict_probability)
		free(prob_estimates);

	return predict_label;
}

/**
  svm model을 memory로 load..
*/  
void LibSVMClassifier::loadModel(std::string fileName)
{	
	if((model=svm_load_model (  (char*)fileName.c_str()	))==0) {
		fprintf(stderr,"can't open model file %s\n",(char*)fileName.c_str()   );
		exit(1);
	}
	if(predict_probability) 
	{
		if(svm_check_probability_model(model)==0) 
		{
			fprintf(stderr,"Model does not support probabiliy estimates\n");
			exit(1);
		}
	}
	else
	{
		if(svm_check_probability_model(model)!=0)
			printf("Model supports probability estimates, but disabled in prediction.\n");
	}
	if( x != NULL)
	{
		free(x);
		x = NULL;
	}
	x = (struct svm_node *) malloc( SVM_MAX_WORDS * sizeof(struct svm_node));
	svm_type=svm_get_svm_type(model);
	nr_class=svm_get_nr_class(model);
	std::cout << "Classifying model is loaded.\n";
}



